<?php


namespace app\services\delivery;


use app\common\Consts;
use app\models\delivery\DeliveryOrderModel;
use app\services\BaseService;
use app\services\cupboard\CupboardService;
use app\services\cupboard\FranchiserService;
use app\services\user\AdminUserService;
use think\facade\Db;

class DeliveryService extends BaseService
{
    protected static function initModel()
    {
        return new DeliveryOrderModel();
    }

    protected static $statusTxt = [
        0 => '进行中',
        1 => '已完成',
        2 => '超时结束',
        3 => '已关闭'
    ];

    /**
     * @param $userInfo 用户信息
     * @param $type 0全部 1配货 2补货
     * @param $orderField 排序 distance time
     * @param $lng 经度
     * @param $lat 维度
     * @param $orderStatus 0进行中 1已完成 2超时结束
     * @param $page
     * @param $limit
     * @param $team 0只看自己 1查看团队
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getDriverOrderListService($userInfo, $type, $orderField, $lng, $lat, $orderStatus, $page, $limit, $team)
    {
        $driverId = $userInfo->id;
        $operatorId = $userInfo->operator_id;
        $roleId = $userInfo->role_id;
        if (!in_array($roleId, [Consts::DRIVER_CLASS_ROLE_ID, Consts::DRIVER_ROLE_ID, Consts::GENERAL_MANAGER_ROLE_ID])) {
            throw new \Exception('非法请求');
        }
        if ($roleId == Consts::DRIVER_CLASS_ROLE_ID && $team == 1) {
            $driverId = AdminUserService::getDriverIdArr($driverId);
        }
        // 查看团队
        if ($roleId == Consts::GENERAL_MANAGER_ROLE_ID) {
            $userInfo = AdminUserService::getUserInfo($driverId);
            $driverClassId = AdminUserService::getChildDriverClass($userInfo['city_id']);
            $driverId = AdminUserService::getDriverIdArr($driverClassId);
            $driverId = array_merge($driverClassId, $driverId);
        }
        // 从redis拿出运营商的设备ID 距离由近到远排序
        $cupboardList = CupboardService::getCupboardsByRedis($operatorId, $lng, $lat, 20000);
        if (!$cupboardList) {
            return [];
        }
        // 柜机ID=>距离的数组
        $cupboardDistance = [];
        // 柜机ID数组
        $cupboardIds = [];
        foreach ($cupboardList as $item) {
            $cupboardId = $item[0];
            $distance = $item[1];
            array_push($cupboardIds, $cupboardId);
            $cupboardDistance[$cupboardId] = $distance;
        }
        // 获取司机补货，配货设备id列表
        $where = [];
        $where[] = ['driver_id', 'in', $driverId];
        if ($type > 0) {
            $where[] = ['group_type', '=', $type];
        }
        $where[] = ['status', '=', $orderStatus];
        $field = 'cupboard_id,franchiser_id,driver_id,order_no,create_time,status,finish_time,over_time,close_time,imei,
        lat,lng,address,cupboard_name,franchiser_phone,franchiser_name';
        if ($orderStatus == 0) {
            $orderBy = ['create_time' => 'asc'];
        } elseif ($orderStatus == 1) {
            $orderBy = ['finish_time' => 'desc'];
        } else {
            $orderBy = ['over_time' => 'desc'];
        }

        if ($orderField == 'distance' && in_array($orderStatus, [0, 1])) {
            $idStr = implode(',', $cupboardIds);
            $orderRaw = "FIELD(cupboard_id,$idStr)";
            $list = self::initModel()->field($field)->where($where)->orderRaw($orderRaw)
                ->paginate(['list_rows' => $limit, 'page' => $page])->toArray();
        } else {
            $list = self::initModel()->field($field)->where($where)->order($orderBy)
                ->paginate(['list_rows' => $limit, 'page' => $page])->toArray();
        }
        foreach ($list['data'] as &$value) {
            // 订单内容
            $value['driver_name'] = AdminUserService::getUserNick($value['driver_id']);
            $value['time_txt'] = time_tran(strtotime($value['create_time']));
            $value['order_status'] = self::$statusTxt[$value['status']];
            $value['distance'] = isset($cupboardDistance[$value['cupboard_id']]) ? $cupboardDistance[$value['cupboard_id']] : 0;
            // 柜机信息
            if ($value['status'] == 0) {
                $cupboardField = 'id,lat,lng,imei,address,online_status,name';
                $cupboardInfo = Db::connect('cupboard')
                    ->table('cupboard')
                    ->field($cupboardField)
                    ->where('id', $value['cupboard_id'])
                    ->find();
                // 商户信息
                $franchiserInfo = Db::connect('cupboard')
                    ->table('franchiser')
                    ->field('phone,name')
                    ->where('id', $value['franchiser_id'])
                    ->find();
            } else {
                $cupboardInfo = [
                    'id' => $value['cupboard_id'],
                    'lat' => $value['lat'],
                    'lng' => $value['lng'],
                    'imei' => $value['imei'],
                    'address' => $value['address'],
                    'name' => $value['cupboard_name'],
                ];
                $franchiserInfo = [
                    'phone' => $value['franchiser_phone'],
                    'name' => $value['franchiser_name']
                ];
            }
            $value['cupboard_info'] = $cupboardInfo;
            $value['franchiser_info'] = $franchiserInfo;
        }
        return $list;
    }

    /**
     * 获取订单详情
     * @param $orderNo
     * @return DeliveryOrderModel|array|mixed|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getDriverOrderDetailService($orderNo)
    {
        $field = 'cupboard_id,franchiser_id,driver_id,order_no,create_time,status,finish_time,over_time,close_time';
        $info = self::initModel()->field($field)->where('order_no', $orderNo)->find();
        if (!$info) {
            throw new \Exception('订单不存在');
        }
        // 订单内容
        $info['driver_name'] = AdminUserService::getUserNick($info['driver_id']);
        $info['time_txt'] = time_tran(strtotime($info['create_time']));
        $info['order_status'] = self::$statusTxt[$info['status']];
        $info['record'] = $info['status'] != 1 ? [] : DeliveryOrderRecordService::getRecordByOrderNo($info['order_no']);
        // 柜机信息
        $cupboardField = 'id,lat,lng,serial,imei,address,online_status,group_id,name';
        $cupboardInfo = Db::connect('cupboard')
            ->table('cupboard')
            ->field($cupboardField)
            ->where('id', $info['cupboard_id'])
            ->find();
        $info['cupboard_info'] = $cupboardInfo;
        // 商户信息
        $franchiserInfo = Db::connect('cupboard')
            ->table('franchiser')
            ->field('phone,name')
            ->where('id', $info['franchiser_id'])
            ->find();
        $info['franchiser_info'] = $franchiserInfo;
        return $info;
    }

    /**
     * 获取配货数量
     */
    public static function getDriverPrepareNum($driverId)
    {
        $num = self::initModel()->where('driver_id', $driverId)->where('group_type', 1)->where('status', 0)->count('id');
        return $num;
    }

    /**
     * 获取补货数量
     */
    public static function getReplenishmentNum($driverId)
    {
        $num = self::initModel()->where('driver_id', $driverId)->where('group_type', 2)->where('status', 0)->count('id');
        return $num;
    }

    /**
     * 获取订单信息
     * @param $orderNo
     * @return DeliveryOrderModel|array|mixed|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getOrderInfo($orderNo)
    {
        $info = self::initModel()->where('order_no', $orderNo)->find();
        return $info;
    }

    /**
     * 确认订单
     * @param $orderNo
     * @param $goodsArr
     * @return bool
     * @throws \Exception
     */
    public static function confirmOrderService($orderNo, $goodsArr, $isDeice)
    {
        Db::startTrans();
        try {
            $orderInfo = self::initModel()->where('order_no', $orderNo)->find();
            if (!$orderInfo) {
                throw new \Exception('订单不存在');
            }
            if ($orderInfo['status'] != 0) {
                throw new \Exception('订单已完成');
            }
            // 添加出入库记录
            $record = [];
            $content = [];
            $num = 0;
            foreach ($goodsArr as $key => $value) {
                $goodsList = explode(':', $value);
                if (!is_array($goodsList) || count($goodsList) != 3) {
                    throw new \Exception('参数格式错误！！！');
                }
                $goodsId = $goodsList[0];
                $putInNum = $goodsList[1] ?: 0;
                $num += $putInNum;
                $takeOutNum = $goodsList[2] ?: 0;
                $goodsName = GoodsService::getGoodsName($goodsId);
                $record[$key] = [
                    'operator_id' => $orderInfo['operator_id'],
                    'cupboard_id' => $orderInfo['cupboard_id'],
                    'imei' => $orderInfo['imei'],
                    'franchiser_id' => $orderInfo['franchiser_id'],
                    'group_type' => $orderInfo['group_type'],
                    'order_no' => $orderInfo['order_no'],
                    'goods_id' => $goodsId,
                    'put_in_num' => $putInNum,
                    'take_out_num' => $takeOutNum,
                    'goods_name' => $goodsName,
                ];
                $content[$key] = [
                    'goods_id' => $goodsId,
                    'put_in_num' => $putInNum,
                    'take_out_num' => $takeOutNum,
                    'goods_name' => $goodsName,
                ];
            }
            DeliveryOrderRecordService::create($record);
            // 更新订单信息
            if (time() - strtotime($orderInfo['create_time']) > 86400) {
                $time = 0;
            } else {
                $time = 1;
            }
            $cupboardInfo = CupboardService::getCupboardInfo($orderInfo['cupboard_id']);
            $franchiserInfo = FranchiserService::getFranchiserInfo($orderInfo['franchiser_id']);
            self::initModel()::update([
                'status' => 1,
                'is_deice' => $isDeice,
                'franchiser_phone' => $franchiserInfo['phone'],
                'franchiser_name' => $franchiserInfo['name'],
                'cupboard_name' => $cupboardInfo['name'],
                'lng' => $cupboardInfo['lng'],
                'lat' => $cupboardInfo['lat'],
                'address' => $cupboardInfo['address'],
                'content' => json_encode($content, JSON_UNESCAPED_UNICODE),
                'completed_within_one_day' => $time,
                'finish_time' => date('Y-m-d H:i:s')
            ], ['order_no' => $orderNo]);
            Db::commit();
            // 更新组是否完成
            $count = self::initModel()->where('group_no', $orderInfo['group_no'])->where('status', 0)->count();
            if ($count == 0) {
                DeliveryGroupService::updateData($orderInfo['group_no'], [
                    'status' => 1
                ]);
            }
//            event('ChangeLayerProductNum', ['cupboard_id' => $orderInfo['cupboard_id'], 'num' => $num]);
            return true;
        } catch (\Exception $exception) {
            Db::rollback();
            throw new \Exception($exception->getMessage());
        }
    }

    /**
     * 获取订单组进行中的订单数量
     * @param $groupNo
     * @return int
     * @throws \think\db\exception\DbException
     */
    public static function getCompleteOrderInfo($groupNo)
    {
        $count = self::initModel()->where('group_no', $groupNo)->where('status', 0)->count();
        return $count;
    }

    /**
     * 获取司机未完成订单数量
     * @param $driverId
     * @return int
     * @throws \think\db\exception\DbException
     */
    public static function getDriverOrderCount($driverId)
    {
        $count = self::initModel()->where('driver_id', $driverId)->where('status', 0)->count();
        return $count;
    }
}